package com.ruoyi.forum.utils;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author: houyong
 * @date: 2025年11月13日 16:40
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    public static final String PATTERN_1 = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_2 = "yyyy-MM-dd";
    public static final String PATTERN_3 = "HH:mm";
    public static final String PATTERN_4 = "M月d日";
    public static final String PATTERN_5 = "MM/dd/yyyy";
    public static final String PATTERN_6 = "yyyy-MM-dd HH:mm";
    public static final String PATTERN_7 = "yyyy年MM月dd日";
    public static final String PATTERN_8 = "yyyyMMdd";
    public static final String PATTERN_9 = "yyyy-MM-dd HH";
    private static final String[] parsePatterns = new String[]{"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm"};

    public DateUtils() {
    }

    public static long str2DateL_new(String dateStr) {
        try {
            return callbackDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr).getTime();
        } catch (ParseException var2) {
            var2.printStackTrace();
            return -1L;
        }
    }

    public static Long str2Long(String dateStr, String pattern) {
        try {
            return callbackDateFormat(pattern).parse(dateStr).getTime();
        } catch (ParseException var3) {
            var3.printStackTrace();
            return null;
        }
    }

    public static long str2DateL(String dateStr) {
        try {
            return callbackDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr + " 00:00:00").getTime();
        } catch (ParseException var2) {
            var2.printStackTrace();
            return -1L;
        }
    }

    public static long str2EDateL(String dateStr) {
        try {
            return callbackDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr + " 23:59:59").getTime();
        } catch (ParseException var2) {
            var2.printStackTrace();
            return -1L;
        }
    }

    public static String long2Str(Long milltime, String pattern) {
        Calendar cal = Calendar.getInstance();
        if (milltime == null) {
            return null;
        } else {
            cal.setTimeInMillis(milltime);
            return callbackDateFormat(pattern).format(cal.getTime());
        }
    }

    public static Long calendarInLong() {
        Calendar cal = Calendar.getInstance(Locale.CHINA);
        return cal.getTimeInMillis();
    }

    private static DateFormat callbackDateFormat(String pattern) {
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        dateFormat.setLenient(false);
        return dateFormat;
    }

    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }

    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }

        return formatDate;
    }

    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    public static int getYear(Calendar cal) {
        return cal.get(1);
    }

    public static int getMonth(Calendar cal) {
        return cal.get(2);
    }

    public static int getDay(Calendar cal) {
        return cal.get(5);
    }

    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        } else {
            try {
                return parseDate(str.toString(), parsePatterns);
            } catch (ParseException var2) {
                return null;
            }
        }
    }

    public static long pastDays(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / 86400000L;
    }

    public static Date getDateStart(Date date) {
        if (date == null) {
            return null;
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            try {
                date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 00:00:00");
            } catch (ParseException var3) {
                var3.printStackTrace();
            }

            return date;
        }
    }

    public static Date getDateEnd(Date date) {
        if (date == null) {
            return null;
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            try {
                date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 23:59:59");
            } catch (ParseException var3) {
                var3.printStackTrace();
            }

            return date;
        }
    }

    public static boolean isDate(String timeString) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        format.setLenient(false);

        try {
            format.parse(timeString);
            return true;
        } catch (Exception var3) {
            return false;
        }
    }

    public static String dateFormat(Date timestamp) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(timestamp);
    }

    public static Timestamp getSysTimestamp() {
        return new Timestamp(System.currentTimeMillis());
    }

    public static Date getSysDate() {
        return new Date();
    }

    public static String getDateRandom() {
        String s = (new SimpleDateFormat("yyyyMMddHHmmssSSS")).format(new Date());
        return s;
    }

    public static String getCurrentYearAndMonthString() {
        StringBuilder result = new StringBuilder();
        Calendar cal = Calendar.getInstance();
        int year = cal.get(1);
        int month = cal.get(2) + 1;
        result.append(year).append("-").append(month);
        return result.toString();
    }

    public static String getLastMonthString() {
        StringBuilder result = new StringBuilder();
        Calendar cal = Calendar.getInstance();
        int year = cal.get(1);
        int month = cal.get(2);
        result.append(year).append("-").append(month);
        return result.toString();
    }

    public static Long getLastMonthFristDayTimestamp() {
        Calendar cal_1 = Calendar.getInstance();
        cal_1.add(2, -1);
        cal_1.set(5, 1);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return str2DateL(format.format(cal_1.getTime()));
    }

    public static Long getLastMonthLastDayTimestamp() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cale = Calendar.getInstance();
        cale.set(5, 1);
        return str2DateL(format.format(cale.getTime()));
    }

    public static String getYestday() {
        Calendar cal = Calendar.getInstance();
        cal.add(5, -1);
        cal.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(cal.getTime());
    }

    public static String getBeforeDays(int n) {
        Calendar cal = Calendar.getInstance();
        cal.add(5, -n);
        cal.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(cal.getTime());
    }

    public static String getAfterDays(int n) {
        Calendar cal = Calendar.getInstance();
        cal.add(5, n);
        cal.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(cal.getTime());
    }

    public static String getSetDateBeforeDays(Date date, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(5, cal.get(5) - n);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(cal.getTime());
    }

    public static String getSetDateAfterDays(Date date, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(5, cal.get(5) + n);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(cal.getTime());
    }

    public static List<String> getSetDateAfterDaysBeforeEndDate(Date date, Date endDate, int n) {
        ArrayList dateResult;
        Calendar cal;
        for (dateResult = new ArrayList(); date.before(endDate); date = cal.getTime()) {
            cal = Calendar.getInstance();
            cal.setTime(date);
            cal.set(5, cal.get(5) + n);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            if (!cal.getTime().after(endDate)) {
                dateResult.add(format.format(cal.getTime()));
            }
        }

        return dateResult;
    }

    public static List<String> getSetDateAfterDaysBeforeEndDateV2(Date date, Date endDate, int n) {
        List<String> dateResult = new ArrayList();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(5, cal.get(5) - 1);

        for (date = cal.getTime(); date.before(endDate); date = cal.getTime()) {
            cal.setTime(date);
            cal.set(5, cal.get(5) + n);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            if (!cal.getTime().after(endDate)) {
                dateResult.add(format.format(cal.getTime()));
            }
        }

        return dateResult;
    }

    public static String getTodayStr() {
        Date now = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String nowDateStr = dateFormat.format(now);
        return nowDateStr;
    }

    public static String getYestodayStr() {
        Date yestodayDate = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(yestodayDate);
        calendar.add(5, -1);
        yestodayDate = calendar.getTime();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String yestodayDateStr = formatter.format(yestodayDate);
        return yestodayDateStr;
    }

    public static String getWeekStartDateStr() {
        new Date();
        Calendar calendar = new GregorianCalendar();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        calendar.set(7, 2);
        Date weeksdate = calendar.getTime();
        String weeksdateString = formatter.format(weeksdate);
        return weeksdateString;
    }

    public static String getWeekEndDateStr() {
        new Date();
        Calendar calendar = new GregorianCalendar();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        calendar.set(7, 2);
        calendar.add(5, 6);
        Date weekedate = calendar.getTime();
        String weakedateString = formatter.format(weekedate);
        return weakedateString;
    }

    public static Long getDailyStartTime(Long timeStamp) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        calendar.setTimeInMillis(timeStamp);
        calendar.set(11, 0);
        calendar.set(13, 0);
        calendar.set(12, 0);
        calendar.set(14, 0);
        return calendar.getTimeInMillis();
    }

    public static int getMondayPlus() {
        Calendar cd = Calendar.getInstance();
        int dayOfWeek = cd.get(7) - 1;
        return dayOfWeek == 1 ? 0 : 1 - dayOfWeek;
    }

    public static String getPreviousWeekSunday() {
        int weeks = -1;
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(5, mondayPlus + weeks);
        Date monday = currentDate.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String preMonday = sdf.format(monday);
        return preMonday;
    }

    public static String getPreviousWeekday() {
        int week = -1;
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(5, mondayPlus + 7 * week);
        Date monday = currentDate.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String preMonday = sdf.format(monday);
        return preMonday;
    }

    public static String getCurrentMonthFirstDay() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(2, 0);
        c.set(5, 1);
        String day1 = format.format(c.getTime());
        return day1;
    }

    public static String getCurrentMonthLastDay() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar ca = Calendar.getInstance();
        ca.set(5, ca.getActualMaximum(5));
        String day2 = format.format(ca.getTime());
        return day2;
    }

    public static String getPreviousMonthFirstDay() {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        calendar.add(2, -1);
        calendar.set(5, 1);
        return format.format(calendar.getTime());
    }

    public static String getPreviousMonthLastDay() {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(2);
        calendar.set(2, month - 1);
        calendar.set(5, calendar.getActualMaximum(5));
        return sf.format(calendar.getTime());
    }

    public static List<String> getBetweenDate(String startTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> list = new ArrayList();

        try {
            Date startDate = sdf.parse(startTime);
            Date endDate = sdf.parse(endTime);

            for (Calendar calendar = Calendar.getInstance(); startDate.getTime() <= endDate.getTime(); startDate = calendar.getTime()) {
                list.add(sdf.format(startDate));
                calendar.setTime(startDate);
                calendar.add(5, 1);
            }
        } catch (ParseException var7) {
            var7.printStackTrace();
        }

        return list;
    }

    public static int differentDaysByMillisecond(Date date1, Date date2) {
        int days = (int) ((date2.getTime() - date1.getTime()) / 86400000L);
        return days;
    }

    public static int getTodayIndexInThisWeek() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(5, -1);
        int weekIdx = calendar.get(7);
        return weekIdx;
    }

    public static void main(String[] args) throws ParseException {
        System.out.println(getTodayIndexInThisWeek());
        System.out.println(differentDaysByMillisecond(parseDate("2022-11-17"), parseDate("2022-12-17")));
    }
}
